package com.coocaa.ops.admin.base;

import com.coocaa.ops.common.core.base.BaseBizImpl;
import com.coocaa.ops.common.core.base.enums.ResourceStatusEnums;
import com.coocaa.ops.common.core.base.entity.BaseHistoryTableEntity;
import com.coocaa.ops.common.core.base.entity.BaseOriginTableEntity;
import com.coocaa.ops.common.core.base.mapper.IBaseHistoryMapper;
import com.coocaa.ops.common.core.base.mapper.IBaseMapper;
import com.coocaa.ops.common.core.base.mybatis.QueryTemplate;
import com.coocaa.ops.common.core.base.mybatis.UpdateTemplate;
import com.coocaa.ops.common.core.base.util.BeanCopyUtil;
import com.coocaa.ops.common.tool.date.DateUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;
import java.util.List;

/**
 * @author bijiahao
 * @date : 2018/9/6.
 * @description: 抽象biz层业务实现-适用于带副本的-标准表结构-实体类
 */
public abstract class AbstractBizImpl<M extends IBaseMapper<T>, T extends BaseOriginTableEntity> extends BaseBizImpl<M, T> {

    /**
     * 获取历史表对应的Mapper接口
     *
     * @return
     */
    abstract public IBaseHistoryMapper getHistoryMapper();

    /**
     * 新增-历史表信息
     *
     * @param historyEntity
     * @param <TH>
     * @return
     */
    public <TH extends BaseHistoryTableEntity> TH addHistory(TH historyEntity) {
        historyEntity.setFlag(1);
        Date date = DateUtil.getCurDate();
        if (null == historyEntity.getCreatedDate()) {
            historyEntity.setCreatedDate(date);
        }
        historyEntity.setLastUpdateDate(date);
        getHistoryMapper().insert(historyEntity);
        return historyEntity;
    }

    /**
     * 获取推荐位基础信息-根据ID和版本
     *
     * @param id
     * @param version
     * @return
     */
    public T getEntityByIdAndVersion(Integer id, Integer version) {
        //查询-根据自增ID
        T originEntity = (T) super.queryById(id);
        if (null != version && !version.equals(originEntity.getCurrentVersion())) {
            //副本信息
            BaseHistoryTableEntity historyEntity = this.queryHistoryByIdAndVersion(id, version);
            //创建原始表实体类实例
            T entity = createOriginEntityNewInstance();
            BeanCopyUtil.copyOrig2Target(historyEntity, entity, "实体类复制");
            //用于 区分普通编辑与副本的编辑 yes代表 副本的编辑
            entity.setDuplicateEdit(true);
            return entity;
        }
        //用于 区分普通编辑与副本的编辑 no代表 普通编辑
        originEntity.setDuplicateEdit(false);
        return originEntity;
    }

    /**
     * 查询副本历史信息-根据ID和版本
     *
     * @param id
     * @param version
     * @return
     */
    public <TH extends BaseHistoryTableEntity> TH queryHistoryByIdAndVersion(Integer id, Integer version) {
        QueryTemplate<T> queryTemplate = getIdAndVersionQuery(id, version);
        List<TH> list = getHistoryMapper().selectList(queryTemplate);
        return CollectionUtils.isNotEmpty(list) ? list.get(0) : null;
    }

    /**
     * 更新原始表副本标识
     *
     * @param id
     * @param version
     */
    public void updateDuplicateVersion(Integer id, Integer version, Integer userId) {
        T update = createOriginEntityNewInstance();
        update.setId(id);
        update.setDuplicateVersion(version);
        update.setModifier(userId);
        this.updateById(update);
    }

    /**
     * 更新原始表flag
     *
     * @param id
     * @param userId
     * @param flag
     */
    public void updateFlag(Integer id, Integer userId, int flag) {
        T updateOriginTableEntity = this.createOriginEntityNewInstance();
        updateOriginTableEntity.setId(id);
        updateOriginTableEntity.setModifier(userId);
        updateOriginTableEntity.setFlag(flag);
        updateOriginTableEntity.setLastUpdateDate(DateUtil.getCurDate());
        getMapper().updateById(updateOriginTableEntity);
    }


    /**
     * 更新历史表信息
     *
     * @param historyEntity
     * @param id
     * @param version
     * @param <TH>
     * @return
     */
    public <TH extends BaseHistoryTableEntity> TH updateHistory(TH historyEntity, Integer id, Integer version) {
        UpdateTemplate<T> updateTemplate = getIdAndVersionUpdate(id, version);
        getHistoryMapper().update(historyEntity, updateTemplate);
        return historyEntity;
    }

    /**
     * 更新历史表状态
     *
     * @param id
     * @param version
     * @param userId
     * @param status
     */
    public void updateHistoryStatus(Integer id, Integer version, Integer userId, int status) {
        UpdateTemplate<T> updateTemplate = getIdAndVersionUpdate(id, version);
        BaseHistoryTableEntity updateHistoryEntity = this.createHistoryEntityNewInstance();
        updateHistoryEntity.setModifier(userId);
        updateHistoryEntity.setStatus(status);
        updateHistoryEntity.setLastUpdateDate(DateUtil.getCurDate());
        getHistoryMapper().update(updateHistoryEntity, updateTemplate);
    }

    /**
     * 更新历史表flag
     *
     * @param id
     * @param version
     * @param userId
     * @param flag
     */
    public void updateHistoryFlag(Integer id, Integer version, Integer userId, int flag) {
        UpdateTemplate<T> wrapper = getIdAndVersionUpdate(id, version);
        BaseHistoryTableEntity updateHistoryEntity = this.createHistoryEntityNewInstance();
        updateHistoryEntity.setModifier(userId);
        updateHistoryEntity.setFlag(flag);
        updateHistoryEntity.setLastUpdateDate(DateUtil.getCurDate());
        getHistoryMapper().update(updateHistoryEntity, wrapper);
    }

    /**
     * 是否已存在副本
     *
     * @param id
     * @return
     */
    public boolean isExistCopy(Integer id) {
        QueryTemplate<T> wrapper = new QueryTemplate<>();
        wrapper.eq("flag", 1)
                .eq("id", id)
                .in("status", new Integer[]{ResourceStatusEnums.DRAFT.getStatus(), ResourceStatusEnums.TO_AUDITING.getStatus()});
        return getHistoryMapper().selectCount(wrapper) > 0;
    }

    /**
     * 副本是否被删除
     *
     * @param id
     * @param version
     * @return
     */
    public boolean isCopyHasDel(Integer id, Integer version) {
        QueryTemplate<T> wrapper = getIdAndVersionQuery(id, version);
        wrapper.eq("flag", 1);
        return getHistoryMapper().selectCount(wrapper) == 0;
    }

    /**
     * 创建原始表实体类实例
     *
     * @return
     */
    abstract public T createOriginEntityNewInstance();


    /**
     * 创建历史表实体类实例
     *
     * @param <TH>
     * @return
     */
    abstract public <TH extends BaseHistoryTableEntity> TH createHistoryEntityNewInstance();


    protected QueryTemplate<T> getIdAndVersionQuery(Integer id, Integer version) {
        QueryTemplate<T> queryTemplate = new QueryTemplate();
        queryTemplate.eq("id", id)
                .eq("current_version", version);
        return queryTemplate;
    }

    protected UpdateTemplate<T> getIdAndVersionUpdate(Integer id, Integer version) {
        UpdateTemplate<T> updateTemplate = new UpdateTemplate();
        updateTemplate.eq("id", id)
                .eq("current_version", version);
        return updateTemplate;
    }
}
